﻿        using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel.Web;
using System.Data.Services;
using VsxFactory.Modeling.Repository;
using VsxFactory.Modeling.Strategies;

namespace VsxFactory.Repository.StrategiesGallery
{
    public class PackageDataContext : IUpdatable
    {
        class LocalPackageRepositoryWrapper : LocalPackageRepository
        {
            public LocalPackageRepositoryWrapper(IStrategyContext context, string packageKind)
                : base(context, packageKind)
            {
                InitializeData();
            }

            protected override List<PackageInfo> PackageCache
            {
                get
                {
                    return HttpContext.Current.Cache["__Packages__"] as List<PackageInfo>;
                }
                set
                {
                    HttpContext.Current.Cache["__Packages__"] = value;
                }
            }

            protected override PackageInfo PreparePackageInfo(PackageInfo package)
            {
                // Récupération du l'adresse source
                // A la dure
                int pos = HttpContext.Current.Request.Url.OriginalString.IndexOf("Strategies.svc", StringComparison.CurrentCultureIgnoreCase);
                package.RepositorySource = HttpContext.Current.Request.Url.OriginalString.Substring(0, pos - 1);
                return base.PreparePackageInfo(package);
            }

            protected override void DownloadPackage(PackageInfo package)
            {
                // Do nothing                
            }
        }

        private List<PackageInfo> pendings = new List<PackageInfo>();
        private IPackageRepository repository;

        public PackageDataContext(string kind)
        {
            var context = new ServerStrategyContext();
            repository = new LocalPackageRepositoryWrapper(context, kind);
        }

        public IQueryable<PackageInfo> Packages
        {
            get
            {
                return repository.GetPackages();
            }
        }

        public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
        }

        public void ClearChanges()
        {
            pendings.Clear();
        }

        public object CreateResource(string containerName, string fullTypeName)
        {
            // Mono type
            var pi = new PackageInfo();
            pendings.Add(pi);
            return pi;
        }

        public void DeleteResource(object targetResource)
        {
            var pi = (PackageInfo)targetResource;
            repository.Uninstall(pi);
        }

        public object GetResource(IQueryable query, string fullTypeName)
        {
            var result = query.Cast<PackageInfo>().FirstOrDefault();
            return result;
        }

        public object GetValue(object targetResource, string propertyName)
        {
            var p = typeof(PackageInfo).GetProperty(propertyName);
            return p.GetValue(targetResource, null);
        }

        public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {

        }

        public object ResetResource(object resource)
        {
            var old = resource as PackageInfo;
            var pi = new PackageInfo();
            pi.ID = old.ID;
            pi.Authors = old.Authors;
            pi.Description = old.Description;
            pi.Kind = old.Kind;
            pi.LicenseUrl = old.LicenseUrl;
            pi.Name = old.Name;
            pi.RepositorySource = String.Empty;
            pi.RequireLicenseAcceptance = old.RequireLicenseAcceptance;
            pi.Version = old.Version;
            return pi;
        }

        public object ResolveResource(object resource)
        {
            if (pendings.Count == 0)
            {
                var pi = resource as PackageInfo;
                repository.InstallPackage(pi);
            }
            return resource;
        }

        public void SaveChanges()
        {
            foreach (var pi in pendings)
                repository.InstallPackage(pi);
        }

        public void SetReference(object targetResource, string propertyName, object propertyValue)
        {
        }

        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            var p = typeof(PackageInfo).GetProperty(propertyName);
            p.SetValue(targetResource, propertyValue, null);
        }
    }

}